package com.travelsupport.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.DefaultClientConnection;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;


public class NetworkController {
	private Context context;
	private String TAG = com.travelsupport.common.Common.TAG;
	private String URI = com.travelsupport.common.Common.URI;
	private static String DB_PATH = com.travelsupport.common.Common.DB_FILEPATH;
	private static String DB_NAME = com.travelsupport.common.Common.DB_NAME;
	private final String ALERT_OLD_DB = "Database is old! \n Would you like to update?";
	private final int DIALOG_DOWNLOAD_PROGRESS = 0;
	
	private ProgressDialog mProgressDialog;
	
	private HttpClient client;
	private HttpPost post;
	private String dbVersion = "";
	private String serDbVersion;
	private String dbLink;
	
	public NetworkController(Context context){
		super();
		this.context = context;
		
		client = new DefaultHttpClient();
		post = new HttpPost(URI); 
	}
	
	public boolean checkNetworkConnected(){
		ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		
		final NetworkInfo wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		final NetworkInfo mobile = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
		final NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
		
		if(wifi != null && wifi.isConnected()){
			//Toast.makeText(context, "Connected by wifi", Toast.LENGTH_SHORT).show();
			return true;
		}
		if(mobile != null && mobile.isConnected()){
			//Toast.makeText(context, "Connected by 3G", Toast.LENGTH_SHORT).show();
			return true;
		}
		if(activeNetwork != null && activeNetwork.isConnected()){
			 //Toast.makeText(context, "Connected by activeNetwork ", Toast.LENGTH_SHORT).show();
			 return true;
		}
		return false;
	}
	
	public void CheckLatestDbVersion(String curDbVersion){		
		RequestDbVersion resquestDbVersion = new RequestDbVersion();
		resquestDbVersion.execute(curDbVersion);
	} 
	
	private class RequestDbVersion extends AsyncTask<String, Void, JSONObject>{
		String curDbVersion;
		@Override
		protected JSONObject doInBackground(String... params) {
			try {
				HttpResponse respone;
				curDbVersion = params[0];
				Log.i(TAG, "send: " + dbVersion);
				
				List<NameValuePair> pairs = new ArrayList<NameValuePair>();
				pairs.add(new BasicNameValuePair("dbVersion", dbVersion));
				
				post.setEntity(new UrlEncodedFormEntity(pairs));
				try{
					respone = client.execute(post);
				} catch(IOException ioe){
					Toast.makeText(context, "Can not connect to server!", Toast.LENGTH_SHORT).show();
					return null;
				}
				
				int status = respone.getStatusLine().getStatusCode();
				Log.i(TAG, "status Code: " + status);
				
				if(status == 200){
					HttpEntity entity = respone.getEntity();
					String data = EntityUtils.toString(entity);
					JSONObject last = new JSONObject(data);
					return last;
				}
				
			} catch (Exception e) {
				Log.e(TAG, "Request to server error:" + e.toString());
				e.printStackTrace();
			}
			return null;
		}
		
		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
			Log.i(TAG, "started.....");
		}
		
		@Override
		protected void onPostExecute(JSONObject result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			Log.i(TAG, "thread done....");
			
			try{
				serDbVersion = result.getString("dbVersion");
				Log.i(TAG, "serDbVersion :=" + serDbVersion + ", curDbVersion := " + curDbVersion);
				
				if(!curDbVersion.equals(serDbVersion)){
					dbLink = result.getString("dbLink");
					Log.i(TAG, "dbLink: " + dbLink);
					
					//Display dialog
					DisplayAlertDialog();
				}
				
			}catch(JSONException je){
				Log.e(TAG, "JSON respone error:" + je.toString());
				je.printStackTrace();
			}
		}
		
		private void DisplayAlertDialog(){
			Builder builder = new AlertDialog.Builder(context);
			builder.setMessage(ALERT_OLD_DB);
			builder.setCancelable(true);
			builder.setPositiveButton("I agree", new OkOnClickListener());
			builder.setNegativeButton("No, later", new CancelOnClickListener());
			AlertDialog dialog = builder.create();
			dialog.show();
		}
		
		private final class OkOnClickListener 
		implements DialogInterface.OnClickListener{
			@Override
			public void onClick(DialogInterface dialog, int which) {
				//Toast.makeText(context, "Agree", Toast.LENGTH_SHORT).show();
				mProgressDialog = new ProgressDialog(context);
				mProgressDialog.setMessage("Dowloading...");
				mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
				mProgressDialog.setCancelable(false);
				mProgressDialog.show();
				
				DownloadFile downloadFile = new DownloadFile();
				downloadFile.execute(dbLink);
			}
			
		}
		private final class CancelOnClickListener
		implements DialogInterface.OnClickListener{

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				Toast.makeText(context, "Ignore", Toast.LENGTH_SHORT).show();
			}
			
		}
	
	}

	private class DownloadFile extends AsyncTask<String, Integer, String>{

		@Override
		protected String doInBackground(String... params) {
			try {
				String linkDownload = params[0];
				URL url = new URL(linkDownload);
				
				URLConnection urlConnection = url.openConnection();
				urlConnection.connect();
				
				int lengOfFile = urlConnection.getContentLength();
				Log.i(TAG, "Length of file: " + lengOfFile);
				
				InputStream input = new BufferedInputStream(url.openStream());
				
				String path = DB_PATH + DB_NAME;
				OutputStream output = new FileOutputStream(path);
				
				byte data [] = new byte [1024];
				long total = 0;
				int count;
				
				while((count = input.read(data)) != -1){
					total += count;
					publishProgress((int)(total * 100 / lengOfFile));
					output.write(data, 0, count);
				}
				
				output.flush();
				output.close();
				input.close();
				
			} catch (Exception e) {
				Log.e(TAG, "Download error:" + e.toString());
				e.printStackTrace();
			}
			return null;
		}
		
		@Override
		protected void onProgressUpdate(Integer... values) {
			// TODO Auto-generated method stub
			super.onProgressUpdate(values);
			mProgressDialog.setProgress(values[0]);
		}
		
		@Override
		protected void onPostExecute(String result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			mProgressDialog.dismiss();
		}
	}
}
